package com.cqw.mq;

import com.cqw.constant.MqConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-04-15 14:13
 * @Description:
 */
@Configuration
public class MqConfig {


    //初始化区域消息
    @Bean
    public Queue areaQueue() {
        return new Queue(MqConstant.AREA_QUEUE);
    }

    @Bean
    public DirectExchange areaExchange() {
        return new DirectExchange(MqConstant.AREA_EX);
    }

    @Bean
    public Binding areaBinding() {
        return BindingBuilder.bind(areaQueue()).to(areaExchange()).with(MqConstant.AREA_KEY);
    }


    //测试消息
    @Bean
    public Queue ceShiQueue() {
        return new Queue(MqConstant.CE_SHI_QUEUE);
    }

    @Bean
    public DirectExchange ceShiExchange() {
        return new DirectExchange(MqConstant.CE_SHI_EX);
    }

    @Bean
    public Binding ceShiBinding() {
        return BindingBuilder.bind(ceShiQueue()).to(ceShiExchange()).with(MqConstant.CE_SHI_KEY);
    }


    //日志消息
    @Bean
    public Queue logQueue() {
        return new Queue(MqConstant.LOG_QUEUE);
    }

    @Bean
    public DirectExchange logExchange() {
        return new DirectExchange(MqConstant.LOG_EX);
    }

    @Bean
    public Binding logBinding() {
        return BindingBuilder.bind(logQueue()).to(logExchange()).with(MqConstant.LOG_KEY);
    }


    @Bean
    public Queue logQueue1() {
        return new Queue(MqConstant.LOG_QUEUE1);
    }

    @Bean
    public DirectExchange logExchange1() {
        return new DirectExchange(MqConstant.LOG_EX1);
    }

    @Bean
    public Binding logBinding1() {
        return BindingBuilder.bind(logQueue1()).to(logExchange1()).with(MqConstant.LOG_KEY1);
    }

    //==============下面是测试几种模式start

    /**
     * 第一种模式：直连模式，没有交换机，一个队列，消息直接发送到队列，
     * 消费者会轮询消费消息
     *
     * @return
     */
    @Bean
    public Queue hello() {
        return new Queue("hello");
    }


    /**
     * 第二种模式：广播模式，一个交换机，多个队列绑定在一个交换机上，多个队列会接收到同一个消费，
     * 相当于广播一样
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("logs");
    }

    @Bean
    public Queue fanoutQueue1() {
        return new Queue("fanoutQueue1");
    }

    @Bean
    public Queue fanoutQueue2() {
        return new Queue("fanoutQueue2");
    }

    @Bean
    public Binding fanoutBinding1() {
        return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
    }

    @Bean
    public Binding fanoutBinding2() {
        return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
    }


    /**
     * 第三种模式：direct,一个交换机，可以绑定多个队列，根据不同的
     * 路由key将消息传递到不同的队列中
     */
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("directExchange");
    }

    @Bean
    public Queue directQueue1() {
        return new Queue("directQueue1");
    }

    @Bean
    public Queue directQueue2() {
        return new Queue("directQueue2");
    }

    @Bean
    public Binding directBinding1() {
        return BindingBuilder.bind(directQueue1()).to(directExchange()).with("info");
    }

    @Bean
    public Binding directBinding2() {
        return BindingBuilder.bind(directQueue2()).to(directExchange()).with("error");
    }


    /**
     * 第四种模式：topic
     * * ： 匹配一个字符
     * # ： 匹配0个或多个词
     * 如果匹配多个路由key，一个消息会发送到不同的队列中
     */
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("topicExchange");
    }

    @Bean
    public Queue topicQueue1() {
        return new Queue("topicQueue1");
    }

    @Bean
    public Queue topicQueue2() {
        return new Queue("topicQueue2");
    }

    @Bean
    public Binding topicBinding1() {
        return BindingBuilder.bind(topicQueue1()).to(topicExchange())
                .with("user.*");
    }

    @Bean
    public Binding topicBinding2() {
        return BindingBuilder.bind(topicQueue2()).to(topicExchange())
                .with("user.#");
    }


    /**
     * 第五种模式：延迟消息（死信交换机、死信队列）
     */
    @Bean
    public Queue deadlyQueue() {
        HashMap<String, Object> map = new HashMap<>();
        //把一个队列修改为死信队列
        //消息的最大存活时间
        map.put("x-message-ttl", 10 * 1000);
        //该队列里消息死了，去哪个交互机
        map.put("x-dead-letter-exchange", "deadly.exchange");
        //该队列里消息死了，由哪个路由key来路由到交互机
        map.put("x-dead-letter-routing-key", "deadly.key");
        return new Queue("deadly", true, false, false, map);
    }

    @Bean
    public Exchange deadlyExchange(){
        return new DirectExchange("deadly.exchange");
    }

    /**
     * 新队列
     */
    @Bean("deadly.new.queue")
    public Queue newQueue(){
        return new Queue("deadly.new.queue");
    }

    @Bean
    public Binding deadlyBinding(){
        return BindingBuilder.bind(newQueue()).to(deadlyExchange()).with("deadly.key").noargs();
    }


}
